﻿namespace EFRepositoryTests
{
  using System;
  using System.Collections.Generic;
  using System.Configuration;
  using System.Linq;
  using System.Transactions;
  using Builder;
  using Entities;
  using FluentAssertions;
  using NUnit.Framework;
  using UnityRepository.Repositories;

  [Category("Integration")]
  [TestFixture]
  public class CheckOutRepositoryTests
  {
    private TransactionScope transactionScope;

    private CheckOutRepository checkOutRepository;

    private CartItemRepository cartItemRepository;

    private Document document1;

    private Document document2;

    private DocType docType;

    private SubDocType subDocType1;

    private ManCo manCo1;

    private Domicile domicile;

    private CheckOut checkOut;

    private CheckOut checkOut2;

    [SetUp]
    public void Setup()
    {
      this.transactionScope = new TransactionScope();
      this.checkOutRepository = new CheckOutRepository(ConfigurationManager.ConnectionStrings["Unity"].ConnectionString);
      this.cartItemRepository = new CartItemRepository(ConfigurationManager.ConnectionStrings["Unity"].ConnectionString);

      this.domicile = BuildMeA.Domicile("code", "description");
      this.manCo1 = BuildMeA.ManCo("description1", "code1").WithDomicile(this.domicile);
      this.docType = BuildMeA.DocType("code", "description");
      this.subDocType1 = BuildMeA.SubDocType("code 1", "description 1").WithDocType(this.docType);

      this.document1 =
        BuildMeA.Document("id").WithDocType(this.docType).WithSubDocType(this.subDocType1).WithManCo(this.manCo1);
      this.checkOut = BuildMeA.CheckOut("name", DateTime.Now.AddHours(-2)).WithDocument(this.document1);

      this.document2 =
        BuildMeA.Document("id2").WithDocType(this.docType).WithSubDocType(this.subDocType1).WithManCo(this.manCo1);
      this.checkOut2 = BuildMeA.CheckOut(null, null).WithDocument(this.document1);
    }

    [TearDown]
    public void TearDown()
    {
      this.transactionScope.Dispose();
    }

    [Test]
    public void GivenACheckOut_WhenITryToSaveToTheDatabase_ItIsSavedToTheDatabase()
    {
      Int32 initialCount = this.checkOutRepository.Entities.Count();
      this.checkOutRepository.Create(this.checkOut);

      this.checkOutRepository.Entities.Count().Should().Be(initialCount + 1);
    }

    [Test]
    public void GivenADocumentIdForADocumentThatIsNotCheckedOut_WhenIAskToSeeIfItIsCheckedOut_IGetTheCheckOut()
    {
      this.checkOutRepository.Create(this.checkOut);

      CheckOut checkOutCreated = this.checkOutRepository.GetCheckOut("id");

      checkOutCreated.Should().NotBeNull();
    }

    [Test]
    public void GivenADocumentIdForADocumentThatIsCheckedOut_WhenIAskToSeeIfItIsCheckedOut_IGetNoCheckOut()
    {
      this.checkOutRepository.Create(this.checkOut);

      CheckOut checkOutCreated = this.checkOutRepository.GetCheckOut("id2");

      checkOutCreated.Should().BeNull();
    }

    [Test]
    public void WhenIDeleteACheckOutItem_ThenItIsDeletedFromTheDatabase()
    {
      this.checkOutRepository.Create(this.checkOut);
      CheckOut retrievedCheckOut = this.checkOutRepository.GetCheckOut(this.checkOut.Document.DocumentId);
      this.checkOutRepository.Delete(retrievedCheckOut);
      CheckOut deletedCheckOut =
        this.checkOutRepository.Entities.FirstOrDefault(c => c.DocumentId == retrievedCheckOut.DocumentId);
      deletedCheckOut.Should().BeNull();
    }

    [Test]
    public void GivenACartId_WhenIAskForCheckOutsAgainstIt_IGetTheCheckOuts()
    {
      this.checkOutRepository.Create(this.checkOut);

      var cartItem = new CartItem("cart1") { DocumentId = this.checkOut.DocumentId };
      this.cartItemRepository.Create(cartItem);

      List<CheckOut> checkOuts = this.checkOutRepository.GetCheckOutsForCart("cart1");
      checkOuts.Count.Should().Be(1);
      checkOuts[0].Document.DocumentId.Should().Be("id");
    }
  }
}
